﻿// А - матрицы сравнений
// N - нормализованные матрицы
// W - вектор-столбец относительных весов

namespace hr_1.Model.Algorithm
{
    class Mai
    {
        //Нормализация матриц сравнения А
        private void a_in_n(int k, double[][] A, double[][] N)
        {
            for (int j = 0; j < k; ++j)
            {
                for (int g = 0; g < k; ++g)
                {
                    for (int i = 0; i < k; ++i)
                        N[g][j] = N[g][j] + A[i][j];
                }
            }
            for (int j = 0; j < k; ++j)
            {
                for (int i = 0; i < k; ++i)
                    N[i][j] = A[i][j] / N[i][j];
            }
        }
        //
        private void koef_w(int k, double[][] N, double[] W)
        {
            for (int i = 0; i < k; ++i)
            {
                for (int j = 0; j < k; ++j)
                    W[i] += N[i][j];
                W[i] /= 3;
            }
        }
        //Проверка согласованности матриц сравнения
        private bool checking_consistency(int n, double[][] A, double[] W)
        {
            double ci = 0;
            double ri = 0;
            double cr = 0;
            double n_max = 0;
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; ++j)
                    n_max += A[i][j] * W[j];
            }
            ci = (n_max - n) / (n - 1);
            ri = (1.98 * (n - 2)) / n;
            cr = ci / ri;
            //std::cout<<n_max<<std::endl;
            //std::cout<<ci<<std::endl;
            //std::cout<<ri<<std::endl;
            //std::cout<<cr<<std::endl;
            if (cr > 0.1)
            {
                //std::cout<<"Matrica ne soglasovana"<<std::endl;
                return false;
            }
            return true;
        }

        //Метод анализа иерархий (метод парных сравнений)
        // k - количество критерие оценки
        // m - количество кондидатов
        // n - количество должностей
        // Av - набор матриц сравнений критериев по должности
        // A - набор матриц сравнений кандидатов по критерию
        // W_resulte - вектор относительных весов
        public bool mai(int k, int m, int n, double[][][] Av, double[][][] A, double[][] W_result)
        {
            double[][][] Nv = new double[n][][]; //набор нормированных матриц сравнений критериев по должности
            double[][][] N = new double [k][][]; // набор нормированных матриц сравнений кандидатов по критерию
            double[][] Wv = new double[n][]; //
            double[][] W = new double[k][]; //
            double[][] W_r = new double[n][]; //
            for (int g = 0; g < n; ++g)
            {
                Nv[g] = new double[k][];
                Wv[g] = new double[k];
                for (int i = 0; i < k; ++i)
                {
                    Wv[g][i] = 0;
                    Nv[g][i] = new double[k];
                    for (int j = 0; j < k; ++j)
                        Nv[g][i][j] = 0;
                }
            }
            for (int i = 0; i < k; ++i)
            {
                N[i] = new double[m][];
                W[i] = new double[m];
                for (int j = 0; j < m; ++j)
                {
                    N[i][j] = new double[m];
                    W[i][j] = 0;
                    for (int g = 0; g < m; ++g)
                        N[i][j][g] = 0;
                }
            }
            for (int i = 0; i < n; ++i)
            {
                W_r[i] = new double[m];
                for (int j = 0; j < m; ++j)
                {
                    W_r[i][j] = 0;
                }
            }
            for (int i = 0; i < n; ++i)
                a_in_n(k, Av[i], Nv[i]);
            for (int j = 0; j < k; ++j)
                a_in_n(m, A[j], N[j]);
            for (int i = 0; i < n; ++i)
                koef_w(k, Nv[i], Wv[i]);
            for (int j = 0; j < k; ++j)
                koef_w(m, N[j], W[j]);
            int temp_kol = 0;
            for (int g = 0; g < n; ++g)
            {
                if (!checking_consistency(k, Av[g], Wv[g]))
                    temp_kol++;
            }
            if (temp_kol == 0)
            {
                for (int g = 0; g < n; ++g)
                {
                    for (int j = 0; j < m; ++j)
                    {
                        for (int i = 0; i < k; ++i)
                            W_r[g][j] += W[i][j] * Wv[g][i];
                    }
                }
                for (int i = 0; i < m; ++i)
                {
                    for (int j = 0; j < n; ++j)
                        W_result[i][j] = W_r[j][i];
                }
                return true;
            }
            else
                return false;
        }
    }
}
